using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using SumerCoreDevOps.Infrastructure.Data;
using SumerCoreDevOps.Infrastructure.Workflow;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Shared.Models;
using SumerCoreDevOps.Application.Dtos.Requests.Pipelines;
using SumerCoreDevOps.Application.Dtos.Responses.Pipelines;
namespace SumerCoreDevOps.ControlApi.Controllers;

/// <summary>
/// 流水线管理接口
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class PipelineController : ControllerBase
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly WorkflowEngine _workflowEngine;
    private readonly WorkflowInstanceTracker _instanceTracker;
    private readonly ILogger<PipelineController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="dbProvider">数据库提供者</param>
    /// <param name="workflowEngine">工作流引擎</param>
    /// <param name="instanceTracker">工作流实例跟踪器</param>
    /// <param name="logger">日志记录器</param>
    public PipelineController(
        FreeSQLProvider dbProvider,
        WorkflowEngine workflowEngine,
        WorkflowInstanceTracker instanceTracker,
        ILogger<PipelineController> logger)
    {
        _dbProvider = dbProvider;
        _workflowEngine = workflowEngine;
        _instanceTracker = instanceTracker;
        _logger = logger;
    }

    /// <summary>
    /// 获取所有流水线列表
    /// </summary>
    /// <returns>返回包含所有流水线的列表,每个流水线包括ID、名称、关联的工作流定义、仓库URL、分支、是否启用等信息;数据封装在ApiResponse对象中</returns>
    /// <response code="200">成功返回流水线列表</response>
    [HttpGet]
    [ProducesResponseType(typeof(ApiResponse<List<Pipeline>>), 200)]
    public async Task<IActionResult> GetPipelines()
    {
        var pipelines = await _dbProvider.Orm.Select<Pipeline>()
            .Include(p => p.WorkflowDefinition)
            .ToListAsync();

        return Ok(ApiResponse.Ok(pipelines));
    }

    /// <summary>
    /// 获取流水线详细信息
    /// </summary>
    /// <param name="id">流水线ID</param>
    /// <returns>返回指定流水线的完整信息对象,包括ID、名称、关联的工作流定义详情、仓库配置、创建时间等;如果流水线不存在则返回404状态码和失败信息;数据封装在ApiResponse对象中</returns>
    /// <response code="200">成功返回流水线信息</response>
    /// <response code="404">流水线不存在</response>
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(ApiResponse<Pipeline>), 200)]
    [ProducesResponseType(typeof(ApiResponse<object>), 404)]
    public async Task<IActionResult> GetPipeline(long id)
    {
        var pipeline = await _dbProvider.Orm.Select<Pipeline>()
            .Where(p => p.Id == id)
            .Include(p => p.WorkflowDefinition)
            .FirstAsync();

        if (pipeline == null)
        {
            return NotFound(ApiResponse.Fail($"流水线 {id} 不存在"));
        }

        return Ok(ApiResponse.Ok(pipeline));
    }

    /// <summary>
    /// 创建新流水线
    /// </summary>
    /// <param name="request">创建流水线请求（包含名称、工作流ID、仓库URL等）</param>
    /// <returns>返回新创建的流水线完整信息对象,包括自动生成的流水线ID、名称、工作流定义ID、仓库URL、分支等字段;数据封装在ApiResponse对象中</returns>
    /// <response code="200">成功创建流水线</response>
    [HttpPost]
    [ProducesResponseType(typeof(ApiResponse<Pipeline>), 200)]
    public async Task<IActionResult> CreatePipeline([FromBody] CreatePipelineRequest request)
    {
        var pipeline = new Pipeline
        {
            Name = request.Name,
            WorkflowDefinitionId = request.WorkflowDefinitionId,
            RepositoryUrl = request.RepositoryUrl,
            Branch = request.Branch ?? "main",
            IsEnabled = true,
            CreatedBy = User.Identity?.Name
        };

        pipeline.Id = (long)await _dbProvider.Orm.Insert(pipeline).ExecuteIdentityAsync();

        _logger.LogInformation("创建流水线: {Name}, ID: {Id}", pipeline.Name, pipeline.Id);

        return Ok(ApiResponse.Ok(pipeline));
    }

    /// <summary>
    /// 手动触发执行流水线
    /// </summary>
    /// <param name="id">流水线ID</param>
    /// <param name="request">执行流水线请求（可选的commit信息）</param>
    /// <returns>返回执行结果对象,包含新创建的流水线实例ID和成功提示信息;流水线将异步执行;数据封装在ApiResponse对象中</returns>
    /// <response code="200">成功启动流水线执行</response>
    [HttpPost("{id}/execute")]
    [ProducesResponseType(typeof(ApiResponse<ExecutePipelineResponse>), 200)]
    public async Task<IActionResult> ExecutePipeline(long id, [FromBody] ExecutePipelineRequest? request = null)
    {
        var instanceId = await _workflowEngine.ExecuteWorkflowAsync(
            id,
            request?.CommitHash,
            request?.CommitMessage,
            User.Identity?.Name ?? "System");

        return Ok(ApiResponse.Ok(new ExecutePipelineResponse
        {
            InstanceId = instanceId,
            Message = "流水线已启动"
        }));
    }

    /// <summary>
    /// 获取流水线执行历史记录
    /// </summary>
    /// <param name="id">流水线ID</param>
    /// <param name="limit">返回记录数量限制，默认10条</param>
    /// <returns>返回指定流水线的历史执行记录列表,按时间倒序排列,每条记录包含实例ID、状态、开始时间、结束时间、执行结果等信息;数据封装在ApiResponse对象中</returns>
    /// <response code="200">成功返回执行历史</response>
    [HttpGet("{id}/history")]
    [ProducesResponseType(typeof(ApiResponse<List<PipelineInstance>>), 200)]
    public async Task<IActionResult> GetPipelineHistory(long id, [FromQuery] int limit = 10)
    {
        var history = await _instanceTracker.GetPipelineHistoryAsync(id, limit);
        return Ok(ApiResponse.Ok(history));
    }

    /// <summary>
    /// 启用流水线
    /// </summary>
    /// <param name="id">流水线ID</param>
    /// <returns>返回成功提示信息,数据封装在ApiResponse对象中;启用后的流水线可以被手动触发或自动触发执行</returns>
    /// <response code="200">成功启用流水线</response>
    [HttpPost("{id}/enable")]
    [ProducesResponseType(typeof(ApiResponse<object>), 200)]
    public async Task<IActionResult> EnablePipeline(long id)
    {
        await _dbProvider.Orm.Update<Pipeline>()
            .Set(p => p.IsEnabled, true)
            .Set(p => p.UpdatedAt, DateTime.UtcNow)
            .Where(p => p.Id == id)
            .ExecuteAffrowsAsync();

        return Ok(ApiResponse.Ok(null));
    }

    /// <summary>
    /// 禁用流水线
    /// </summary>
    /// <param name="id">流水线ID</param>
    /// <returns>返回成功提示信息,数据封装在ApiResponse对象中;禁用后的流水线不能被触发执行,正在执行的实例不受影响</returns>
    /// <response code="200">成功禁用流水线</response>
    [HttpPost("{id}/disable")]
    [ProducesResponseType(typeof(ApiResponse<object>), 200)]
    public async Task<IActionResult> DisablePipeline(long id)
    {
        await _dbProvider.Orm.Update<Pipeline>()
            .Set(p => p.IsEnabled, false)
            .Set(p => p.UpdatedAt, DateTime.UtcNow)
            .Where(p => p.Id == id)
            .ExecuteAffrowsAsync();

        return Ok(ApiResponse.Ok(null));
    }
}
